#include <iostream>
#include <unistd.h>
#include <thread>

using namespace std;

void thread_run()
{
    int cnt = 3;

    while(cnt--)
    {
        cout<<"我是一个新线程，正在运行..."<<endl;
        sleep(1);
    }
}
int main()
{
    thread t1(thread_run);

    int cnt = 5;
    while(cnt--)
    {
        cout<<"我是一个主线程，正在运行..."<<endl;
        sleep(1);
    }

    t1.join();

    cout<<"主线程退出"<<endl;

    return 0;
}



















// #include <iostream>
// #include <string>
// #include <vector>
// #include <pthread.h>
// #include <cassert>
// #include <unistd.h>

// using namespace std;

// class threadData
// {
// public:
//     pthread_t tid;
//     char namebuffer[64];
//     int number;
// };
// class threadReturn
// {
// public:
//     int exit_code;
//     int exit_result;
// };
// // 新线程
// // 该函数是可重入函数，属于被重入状态，因为多个执行流执行该函数没有出现数据二义性问题，
// // 在函数内部定义的变量都叫局部变量，具有临时性，在多线程的状态下，也不会有问题，
// // 这说明了每个线程都有自己独立的栈结构
// void* thread_routine(void* args)
// {
//     threadData* td = static_cast<threadData*>(args);   //安全的强制类型转换
//     int cnt = 3;
//     while(cnt)
//     {
//         sleep(1);
//         cout<<"cnt:"<<cnt--<<" &cnt:"<<&cnt<<endl;
        
//     }
//     pthread_exit((void*)111);

//     // threadReturn* tr = new threadReturn;
//     // tr->exit_code = 1;
//     // tr->exit_result = 111;

//     // pthread_exit((void*)tr);
//     // return (void*)tr;

//     // while(true)
//     // {
//     //     cout << "我是新线程，正在运行 name : " << td->namebuffer <<   endl;
//     //     sleep(1);
//     // } 

//     //终止线程
//     // exit(0);     2.这里是不可行的，exit是终止进程的，这里会直接终止掉程序
//     // 3.pthread_exit   终止调用该函数的线程
//     // pthread_exit((void*)111);    //该函数的参数也可被pthread_join获取到
//     // return (void*)td->number;     //1.函数执行结束，return时线程就终止了。
// }
// //创建一批线程 
// int main()
// {
//     #define NUM 3
//     vector<threadData*> threads;
//     //创建一批线程
//     for(int i = 0;i<NUM;++i)
//     {
//         threadData* td = new threadData();
//         td->number = i+1;
//         snprintf(td->namebuffer,sizeof(td->namebuffer),"%s:%d","thread",i);
//         pthread_create(&td->tid,nullptr,thread_routine,td);

//         threads.push_back(td);
//     }
//     for(auto& tids: threads)
//     {
//         cout<< "threads ->name:" << tids->namebuffer <<" tid:"<< tids->tid<< endl;
//     }
//     //线程是可以被cancel取消的，前提是该线程已经跑起来了。
//     sleep(2);
//     for(int i = 0;i<threads.size()/2;++i)
//     {
//         pthread_cancel(threads[i]->tid);
//         cout<<"取消" <<threads[i]->namebuffer<<"成功"<<endl;
//     }

//     for(auto& tids: threads)
//     {
//         void* ret = nullptr;    //这里是void* 
//         int n = pthread_join(tids->tid,(void**)&ret);   //后面的参数是一个二级指针，所以要&
//         assert(n == 0);
//         cout<<"等待" <<tids->namebuffer << "成功"<<" code: "<<(long long)ret <<endl;
//     }
//     // for(auto& tids: threads)
//     // {
//     //     threadReturn* tr = nullptr;    //这里是void* 
//     //     int n = pthread_join(tids->tid,(void**)&tr);   //后面的参数是一个二级指针，所以要&
//     //     assert(n == 0);
//     //     cout<<"等待" <<tids->namebuffer <<" code: "<<tr->exit_code<<
//     //     " result:" <<tr->exit_result << "成功"<<endl;
//     // }
//     cout << "主线程退出 " << endl;
//     // while(true)
//     // {
//     //     cout << "我是主线程，正在运行 " <<  endl;
//     //     sleep(1);
//     // }
//     return 0;
// }




// //创建一批线程 的错误用法
// int main()
// {
//     #define NUM 3
//     vector<pthread_t> tids;
//     //创建一批线程
//     for(int i = 0;i<NUM;++i)
//     {
//         char namebuffer[64];
//         snprintf(namebuffer,sizeof(namebuffer),"%s:%d","thread",i);
//         pthread_t tid;
//         pthread_create(&tid,nullptr,thread_routine,namebuffer);
//         // sleep(1);
//     }
    
//     while(true)
//     {
//         cout << "我是主线程，正在运行 " <<  endl;
//         sleep(1);
//     }
//     return 0;
// }


// 线程的创建
// int main()
// {
//     pthread_t tid;
//     int n = pthread_create(&tid,nullptr,thread_routine,(void*)"thread one");
//     assert(0 == n);
//     (void)n;

//     while(true)
//     {
//         cout << "我是主线程，正在运行 " <<  endl;
//         sleep(1);
//     }
//     return 0;
// }